/**
 * 雷达图
 */
import React from 'react';
import { DL_TYPE, WD_TYPE } from 'src/pages/AnalyseManage/EditReport/components/EditorDataType/EnumConfig';
import { getComponentData } from 'src/services/AnalyseManage';
import { colors, ProvinceData } from './DefaultConfig';
import { ChartService, IProps } from 'src/pages/AnalyseManage/EditReport/components/ChartsType/components/ChartService';

// 引入 ECharts 主模块
import china from '../MapFill/china.json';
import world from '../MapFill/world.json';
import { CHART_LINK } from 'src/pages/AnalyseManage/EditReport/topics';
import PubSub from 'pubsub-js';
import { isNumber } from 'src/libs/utils';

const echarts = require( 'echarts/lib/echarts' );
echarts.registerMap( 'china', china );
echarts.registerMap( 'world', world );

require( 'echarts/lib/chart/map' );
require( 'echarts/lib/chart/scatter' );
require( 'echarts/lib/component/tooltip' );
require( 'echarts/lib/component/geo' );
require( 'echarts/lib/component/visualMap' );

export default class MapBubble extends ChartService {

	state = {
		chartEl: null,
		data: [],
		xField: 'name',
		yField: 'value',
		seriesField: 'category',
		mapType: 'china',
		eventToken: [],
		extra: null,
		dependencies: [],	//	图表联动参数
		isRender: false
	};

	// 入参构建
	itemInfo = ( v ) => {
		return {
			aggregateType: v.modelType === DL_TYPE ? v.aggregateType : '', //	度量的聚合类型
			formatType: v.modelType === WD_TYPE ? v.formatType : '', // 维度的聚合类型v.
			alias: v.title.trim(),
			dataType: v.dataType,
			frontendId: '',
			id: v.name,
			orderType: v.orderType, // 排序方式
			quota: v.modelType === WD_TYPE ? 'WD' : 'DL',
			symbol: '',
			type: v.type,
			value: '',
			dataUnit: v.dataUnit || '',
			precision: v.precision
		};
	};

	async getConditionData() {
		const { config = {} } = this.props;
		const { xAxis = [], yAxis = [], series = [], bubbleSize =[] } = config.data;
		// console.log( config.data );
		if ( xAxis.length && yAxis.length ) {
			const x = xAxis.map( v => this.itemInfo( v ) );
			const y = yAxis.map( v => this.itemInfo( v ) );
			const customParams = bubbleSize.map( v => this.itemInfo( v ) );
			const category = series.map( v => this.itemInfo( v ) );
			const conditions = this.props.config.data.filterFields ? this.props.config.data.filterFields.map( v => v.filterConditions ).flat() : [];
			const request = {
				dataConfig: {
					dataModel: {
						pageId: this.props.pageId,
						tableName: config.data.tableCode,
						x,
						y,
						category,
						conditions: conditions.concat( this.state.dependencies ),
						customParams: { symbolSize: customParams[0] }
					},
					needAutoRefresh: true,
					tableType: 'symbol'
				},
				type: 'map',
				tenantCode: this.props.tenantCode
			};
			let pageResponse = await getComponentData( request );
			if ( pageResponse.data ) {
				const { rows = [], extra } = pageResponse.data.data || {};
				if ( pageResponse.data.success && rows && rows.length > 0 ) {
					return { rows: this.dealData( rows ), extra };
				}
			}
		}
		return { rows: ProvinceData };
	}
	
	// 处理数据
	dealData = ( data ) => {
		return data.map( item => {
			// symbolSize替换为symbolSizeStr，symbolSize字段名会导致汽包大小设置失效
			if ( item.symbolSize ) {
				item[ 'symbolSizeStr' ] = item.symbolSize;
				delete item.symbolSize;
			}
			return item;
		} );
	};

	getConfig = (): any => {
		const { config = {} } = this.props;
		const { style = {} } = config;
		const { dataColorList = [], customColorType = 'piecewise' } = style;
		const inRange = dataColorList.map( t => t.color ) || [];
		const pieces = dataColorList.map( t => {
			return {
				gt: t.gt,
				lte: t.lte,
				color: t.color
			};
		} );
		// console.log( style );
		return {
			tooltip: {
				trigger: 'item',
				formatter: ( params, ticket, callback ) => {
					console.log( params );
					const { yAxis = [] } = this.props.config.data;
					const { name, value, data } = params;
					const { category = [], symbolSizeStr = null, precision = '', dataUnit = '' } = data;
					const yAxisName = yAxis.map( t => t.title ).pop() || '数据';
					const seriesField = category.join( '<br/>' );
					let size = '';
					if ( symbolSizeStr ) {
						size = `${symbolSizeStr} <br/>`;
					}
					let formatValue = value[2] || 0;
					formatValue = isNumber( precision ) ? formatValue.toFixed( precision ) : formatValue;
					formatValue = `${formatValue}${dataUnit}`;
					return `${name}<br/>${yAxisName}: ${formatValue || 0}<br/>${seriesField}<br />${size}`;
				}
			},
			visualMap: {
				min: 0,
				max: this.state.data.map( t => t.value[2] ).reduce( ( num1, num2 ) => {
					return num1 > num2 ? num1 : num2;
				} ),
				type: customColorType,
				pieces: pieces,
				left: 'left',
				top: 'bottom',
				calculable: true,
				inRange: inRange.length ? {
					color: inRange,
				}: {
					color: colors
				}
			},
			geo: {
				map: this.state.mapType,
				label: {
					show: style.isMapLabelShow,
					color: style.mapLabelFontColor,
					fontSize: style.mapLabelFontSize,
					fontWeight: style.mapLabelIsBold ? 'bold': 'normal',
					fontFamily: style.mapLabelFontFamily,
					fontStyle: style.mapLabelIsItalic ? 'italic' : 'normal',
					textDecoration: style.mapLabelIsUnderLine ? 'underline' : 'none',
					// align: style.mapLabelAlignHor,
					// verticalAlign: style.mapLabelAlignVer
				},
			},
			series: [
				{
					name: '数据',
					type: 'scatter',
					coordinateSystem: 'geo',
					data: this.state.data,
					// symbolSize: '10',
					symbolSize: ( value, params ) => {
						// console.log( '--- symbolSize ----', value, params );
						if ( params.data.symbolSizeStr ) {
							const size = +params.data.symbolSizeStr.split( ': ' ).pop();
							const max = this.state.extra.minMax.max;
							let symbolSize = size / ( max / 20 ) + 10;
							// console.log( symbolSize.toFixed() );
							return parseInt( symbolSize.toFixed() );
						}
						return 10;
					},
					label: {
						formatter: '{b}',
						position: 'right',
					},
					emphasis: {
						label: {
							show: false
						}
					},
					itemStyle: {
						color: '#F4E925'
					}
				}, ],
		};
	}

	shouldComponentUpdate( nextProps: Readonly<IProps>, nextState: Readonly<{ dependencies: any }>, nextContext: any ): boolean {
		if ( JSON.stringify( nextProps ) !== JSON.stringify( this.props ) ||
			JSON.stringify( this.state.dependencies ) !== JSON.stringify( nextState.dependencies ) ) return true;
		return false;
	}

	getSnapshotBeforeUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{ dependencies: any }> ): any | null {
		let { config, chartLayout } = this.props;
		let changeObj = Object.create( null );
		const { xAxis = [], yAxis = [], series = [], bubbleSize = [],  filterFields = [], mapType } = config.data || {};
		const { xAxis: pxAxis = [], yAxis: pyAxis = [],
			series: pSeries = [], bubbleSize: pBubbleSize = [], filterFields: pfilterFields = [], mapType: pMapType } = prevProps.config.data || {};

		//	判断数据字段是否变化了
		if ( ( xAxis.length && yAxis.length ) &&
			( JSON.stringify( pxAxis ) !== JSON.stringify( xAxis ) ||
				JSON.stringify( pyAxis ) !== JSON.stringify( yAxis ) ||
				JSON.stringify( pSeries ) !== JSON.stringify( series ) ||
				JSON.stringify( bubbleSize ) !== JSON.stringify( pBubbleSize ) ||
				JSON.stringify( this.state.dependencies ) !== JSON.stringify( prevState.dependencies ) ||
				JSON.stringify( pfilterFields ) !== JSON.stringify( filterFields ) ) ) {
			changeObj.needDataChange = true;
		}

		// 判断类型是否变化了
		if ( config.data.tableCode === prevProps.config.data.tableCode && mapType !== pMapType ) {
			changeObj.needChartTypeChange = true;
		}

		//	判断样式是否改变
		if ( JSON.stringify( prevProps.config.style ) !== JSON.stringify( config.style ) ) {
			changeObj.needStyleChange = true;
		}

		//判断是否因宽高改变重新适应布局
		if ( prevProps.chartLayout.w !== chartLayout.w || prevProps.chartLayout.h !== chartLayout.h ) {
			changeObj.needLayoutChange = true;
		}

		return changeObj;
	}

	initEvent = async () => {
		const { rows: resData, extra } = await this.getConditionData();
		const { mapType } = this.props.config.data || 'china';
		this.setState( {
			data: resData,
			mapType,
			extra,
			isRender: true
		}, () => {
			const dom = document.getElementById( this.props.id );
			if ( !dom ) return;
			const chart = echarts.init( dom );
			chart.setOption( this.getConfig() );
			this.setState( {
				chartEl: chart
			} );

			//	数据联动 组装联动参数
			chart.on( 'click', 'series', ( ev ) => {
				if( !this.props.config.mutual.isChainAvailable ) return;

				const dimension = this.props.config.data.xAxis;
				if( !dimension || dimension.length === 0 ) return;
				const dependencies = dimension.map( ( item, index ) => {
					return {
						formatType: item.formatType,
						id: [ item.name ],
						quota: item.modelType === WD_TYPE ? 'WD' : 'DL',
						symbol: 'EQ',
						value: [ ev.name ]		//	从原数据中找到item，一一对应字段
					};
				} );

				PubSub.publish( CHART_LINK, {
					publisherId: this.props.id,
					listenerIds: this.props.config.mutual.chartsChainIds,
					dimension: dependencies,
					tableCode: this.props.config.data.tableCode
				} );
			} );
		} );
	};

	async componentDidUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{}>, snapshot?: any ) {
		// console.log( 'column', snapshot );
		if ( snapshot.needStyleChange ) {
			this.state.chartEl.setOption( this.getConfig() );
		}

		if ( snapshot.needChartTypeChange ) {
			const { mapType } = this.props.config.data || 'china';
			this.setState( {
				mapType,
				// data: []
			}, () => {
				this.state.chartEl.setOption( this.getConfig() );
				this.props.onValuesChange(
					this.props.config.type,
					this.props.id,
					{
						titleValue: mapType === 'china' ? '中国省份气泡图' : '世界地图',
					},
					'style'
				);
			} );
		}

		if ( snapshot.needLayoutChange ) {
			this.state.chartEl.resize();
		}

		if ( snapshot.needDataChange ) {
			const { rows: resData, extra } = await this.getConditionData();
			this.setState( {
				data: resData,
				extra
			}, () => {
				this.state.chartEl.clear();
				this.state.chartEl.setOption( this.getConfig() );
			} );
		}
	}

	render() {
		return <div id={this.props.id}  style={{ height: '100%', position: 'relative' }}></div>;
	}
};
